package com.bc.trade.service;

import com.bc.common.CommonEnum.NotifyStatus;
import com.bc.common.CommonEnum.OrderStatus;
import com.bc.common.CommonEnum.Resp;

import java.util.Map;

import com.bc.common.PayType;
import com.bc.common.message.AccountBalanceChangeReq;
import com.bc.common.message.AccountBalanceChangeResp;
import com.bc.common.message.AccountTransferReq;
import com.bc.common.message.AccountTransferResp;
import com.bc.common.message.AppidPayReq;
import com.bc.common.message.AppidPayResp;
import com.bc.common.message.AppidWxgjPayReq;
import com.bc.common.message.AppidWxgjPayResp;
import com.bc.common.message.BaseResp;
import com.bc.common.message.DFReq;
import com.bc.common.message.DFResp;
import com.bc.common.message.TransferQrcodeReq;
import com.bc.common.message.TransferQrcodeResp;
import com.bc.common.message.WxgjClearingReq;
import com.bc.common.message.WxgjClearingResp;
import com.bc.trade.channel.ChannelFactory;
import com.bc.trade.channel.IChannel;
import com.bc.trade.channel.yufu.YFChannel;
import com.bc.trade.config.R;
import com.bc.trade.message.BindBankCardReq;
import com.bc.trade.message.BindBankCardResp;
import com.bc.trade.message.BindBankCardVerifyReq;
import com.bc.trade.message.BindBankCardVerifyResp;
import com.bc.trade.message.QueryCardInfoReq;
import com.bc.trade.message.QueryCardInfoResp;
import com.bc.trade.message.QueryOrderReq;
import com.bc.trade.message.QueryOrderResp;
import com.bc.trade.message.QuickPayReq;
import com.bc.trade.message.QuickPayResp;
import com.bc.trade.message.QuickPaySetReq;
import com.bc.trade.message.QuickPaySetResp;
import com.bc.trade.message.RefundReq;
import com.bc.trade.message.RefundResp;
import com.bc.trade.message.SendSMSReq;
import com.bc.trade.message.SendSMSResp;
import com.bc.trade.message.UnionPayReq;
import com.bc.trade.message.UnionPayResp;
import com.bc.trade.model.TradeOrder;
import com.bc.trade.model.TradeStrategy;
import com.bc.trade.noitfy.NotifyThread;
import com.bc.trade.vo.TradeElement;
import com.fs.common.util.FSDate;
import com.fs.common.util.FSIDGenerate;
import com.fs.common.util.FSJson;
import com.fs.common.util.FSLog;

/**
 * 订单服务
 *
 * @author zhongzhanfeng
 *
 */
public class OrderService {

	private static VirtualAccountService accountService = new VirtualAccountService();


	public void visaPay(Map<String, String> reqMap) {
		//TradeOrder order = TradeOrder.createUnionpay(req, tradeElement)
	}

	/**
	 * 代付
	 *
	 * @param req
	 * @param tradeElement
	 * @return
	 * @throws Exception
	 */
	public DFResp df(DFReq req, TradeElement tradeElement) {
		DFResp rsp = new DFResp(req);
		TradeOrder order = TradeOrder.createDF(req, tradeElement);
		// 代付金额需要减去金额+手续费
		Integer dfAmt = order.getAmount() + order.getMerchFee();
		AccountBalanceChangeResp accountRsp = null;
		if ("ntlmh".equals(tradeElement.getTradeStrategy().getChannelCode())
				|| "WMYL".equals(tradeElement.getTradeStrategy().getChannelCode())) {
			accountRsp = accountService.subMoney(true, order.getChannelCode(), order.getMerchCode(), dfAmt);
		} else {
			accountRsp = accountService.subMoney(false, order.getChannelCode(), order.getMerchCode(), dfAmt);
		}
		if (!"SUCCESS".equals(accountRsp.getRespCode())) {
			// 余额不足是不需要撤销的
			rsp.setCodeAndMsg(Resp.Fail.getCode(), accountRsp.getRespMsg());
			order.setBalance(0L);
			order.setOrderStatus(OrderStatus.Fail.getValue());
			order.setRespCode(Resp.Fail.getCode());
			order.setRespMsg(accountRsp.getRespMsg());
			order.save();
			// 明确失败通知商户
			NotifyThread.getInstance().addNotifyOrder(order);
			return rsp;
		}

		// 虚账减钱成功
		order.setBalance(Long.valueOf(accountRsp.getBalance()));
		order.setIsD0(accountRsp.getIsD0());
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			FSLog.api.info("开始请求渠道");
			rsp = channel.df(req, order);
		} catch (Exception e) {
			FSLog.api.error("代付发送至渠道发生异常-> 订单号=" + order.getOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), "系统异常,已撤销");
		} finally {
			setOrderStatusByResp(rsp, order);
			// 失败需要撤销金额
			if (rsp.getRespCode().equals(Resp.Fail.getCode())) {
				order.setOrderStatus(OrderStatus.Cancle.getValue());
				accountService.addMoney(false, order.getChannelCode(), order.getMerchCode(), dfAmt);
				if (!"OPHM".equals(order.getChannelCode()) && !"OPCX".equals(order.getChannelCode())) {
					NotifyThread.getInstance().addNotifyOrder(order);
				}

			}
			order.save();
		}
		return rsp;
	}

	/**
	 * 查询
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 */
	public QueryOrderResp query(QueryOrderReq req) throws Exception {
		QueryOrderResp rsp = new QueryOrderResp(req);
		TradeOrder order = TradeOrder.dao.selectByMerchOrderNo(req.getMerchCode(), req.getMerchOrderNo());

		if (order == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "订单不存在");
		}

		if (req.getPayType().equals(PayType.OWER_QUERY)) {
			order.setCustomerName(PayType.OWER_QUERY);
			IChannel channel = ChannelFactory.get(order.getChannelCode());
			if (order.getPayType().equals(PayType.DF_PERSONAL) || order.getPayType().equals(PayType.DF_COMPANY)) {
				rsp = channel.dfQuery(order);
			} else {
				rsp = channel.query(order);
			}

			if (rsp.getOriginalRespCode().equals(Resp.Fail.getCode())
					|| rsp.getOriginalRespCode().equals(Resp.Success.getCode())) {
				order.setRespCode(rsp.getOriginalRespCode());
				order.setRespMsg(rsp.getOriginalRespMsg());

				if (rsp.getOriginalRespCode().equals(Resp.Success.getCode())) {
					order.setOrderStatus(OrderStatus.Success.getValue());
					order.setPayTime(rsp.getPayTime());
				} else {
					order.setOrderStatus(OrderStatus.Fail.getValue());
				}
				order.update();
			}
		}else {
			if (order.getOrderStatus().equals(OrderStatus.Success.getValue())) {
				rsp.setOriginalRespCode(Resp.Success.getCode());
				rsp.setOriginalRespMsg(Resp.Success.getMsg());
			} else if (order.getOrderStatus().equals(OrderStatus.Fail.getValue())) {
				rsp.setOriginalRespCode(Resp.Fail.getCode());
				rsp.setOriginalRespMsg(order.getRespMsg());
			} else if (OrderStatus.Cancle.getValue().equals(order.getOrderStatus())) {
				rsp.setOriginalRespCode(Resp.Fail.getCode());
				rsp.setOriginalRespMsg(order.getRespMsg());
			} else {
				// 不确定的需要到渠道查询
				IChannel channel = ChannelFactory.get(order.getChannelCode());
				if (order.getPayType().equals(PayType.DF_PERSONAL) || order.getPayType().equals(PayType.DF_COMPANY)) {
					rsp = channel.dfQuery(order);
				} else {
					rsp = channel.query(order);
				}

				if (rsp.getOriginalRespCode().equals(Resp.Fail.getCode())
						|| rsp.getOriginalRespCode().equals(Resp.Success.getCode())) {
					order.setRespCode(rsp.getOriginalRespCode());
					order.setRespMsg(rsp.getOriginalRespMsg());

					if (rsp.getOriginalRespCode().equals(Resp.Success.getCode())) {
						order.setOrderStatus(OrderStatus.Success.getValue());
						order.setPayTime(rsp.getPayTime());
					} else {
						order.setOrderStatus(OrderStatus.Fail.getValue());
					}
					order.update();
				}
			}
		}
		rsp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
		rsp.setCreateTime(order.getCreateTime());
		rsp.setOrderNo(order.getOrderNo());
		rsp.setAmount(order.getAmount().toString());
		return rsp;
	}

	public BaseResp unionPay(UnionPayReq req, TradeElement tradeElement) {
		UnionPayResp rsp = new UnionPayResp(req);
		TradeOrder order = TradeOrder.createUnionpay(req, tradeElement);
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			rsp = channel.unionpay(req, order);
		} catch (Exception e) {
			FSLog.api.error("unionpay exception ->" + req.getMerchCode() + " merchOrderNo=" + req.getMerchOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			setOrderStatusByResp(rsp, order);
			rsp.setOrderNo(order.getOrderNo());
			order.setIsD0(true);
			order.save();
		}
		return rsp;
	}

	public BaseResp quickPaySet(QuickPaySetReq req, TradeElement tradeElement) {
		QuickPaySetResp rsp = new QuickPaySetResp(req);
		TradeOrder order = TradeOrder.quickPaySet(req, tradeElement);
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			rsp = channel.quickPaySet(req, order);
		} catch (Exception e) {
			FSLog.api.error("quickpay exception ->" + req.getMerchCode() + " merchOrderNo=" + req.getMerchOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			setOrderStatusByResp(rsp, order);
			rsp.setOrderNo(order.getOrderNo());
			order.setIsD0(true);
			order.save();
		}
		return rsp;
	}

	public BaseResp quickPay(QuickPayReq req) {
		QuickPayResp rsp = new QuickPayResp(req);
		TradeOrder order = TradeOrder.dao.selectByOrderNo(req.getOrderNo());
		IChannel channel = ChannelFactory.get(order.getChannelCode());
		try {
			rsp = channel.quickPay(req, order);
		} catch (Exception e) {
			FSLog.api.error("quickpay exception ->" + req.getMerchCode(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			if (!Resp.CodeHasExpired.getCode().equals(rsp.getRespCode())) {
				order.setRespCode(rsp.getRespCode());
				order.setRespMsg(rsp.getRespMsg());
				if (order.getRespCode().equals(Resp.Success.getCode())) {
					order.setOrderStatus(OrderStatus.InProcess.getValue());
				} else if (order.getRespCode().equals(Resp.Fail.getCode())) {
					order.setOrderStatus(OrderStatus.Fail.getValue());
				} else {
					order.setOrderStatus(OrderStatus.Unknow.getValue());
				}
				order.update();
			}
		}
		return rsp;
	}

	public BaseResp sendSMS(SendSMSReq req) {
		SendSMSResp rsp = new SendSMSResp(req);
		TradeOrder order = TradeOrder.dao.selectByOrderNo(req.getOrderNo());
		if (order == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "平台订单号不存在");
		}
		IChannel channel = ChannelFactory.get(order.getChannelCode());
		try {
			rsp = channel.sendSMS(req);
		} catch (Exception e) {
			FSLog.api.error("quickpay exception ->" + req.getMerchCode(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		}
		return rsp;
	}

	public BaseResp queryCardInfo(QueryCardInfoReq req) {
		QueryCardInfoResp rsp = new QueryCardInfoResp(req);
		IChannel channel = new YFChannel();
		try {
			rsp = channel.queryCardInfo(req);
		} catch (Exception e) {
			FSLog.api.error("quickpay exception ->" + req.getMerchCode(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		}
		return rsp;
	}

	public BaseResp wxgjRefund(RefundReq req, TradeOrder orignOrder, TradeStrategy ts) {
		RefundResp resp = new RefundResp(req);
		TradeOrder order = TradeOrder.createRefund(req, orignOrder);

		IChannel channel = ChannelFactory.get(ts.getChannelCode());
		try {
			resp = channel.wxgjRefund(req, order, orignOrder);
		} catch (Exception e) {
			FSLog.api.error("微信国际退款:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		} finally {
			if (Resp.Success.getCode().equals(resp.getOriginalRespCode())) {
				order.save();// 退款申请成功后保存在数据库
			}
		}
		return resp;

	}

	public BaseResp wxgjGetClearingData(WxgjClearingReq req, TradeStrategy ts) {
		WxgjClearingResp resp = new WxgjClearingResp(req);
		IChannel channel = ChannelFactory.get(ts.getChannelCode());
		try {
			resp = channel.wxgjGetClearingData(req, ts);
		} catch (Exception e) {
			FSLog.api.error("微信国际清算信息查询:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		} finally {

		}
		return resp;
	}

	public BaseResp wxgjRefundQuery(RefundReq req, TradeOrder orignOrder) {
		RefundResp resp = new RefundResp(req);
		IChannel channel = ChannelFactory.get(orignOrder.getChannelCode());
		try {
			resp = channel.wxgjRefundQuery(req, orignOrder);
		} catch (Exception e) {
			FSLog.api.error("微信国际退款查询:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		} finally {

		}
		return resp;
	}

	public BaseResp refund(RefundReq req, TradeOrder orignOrder) {
		RefundResp rsp = new RefundResp(req);
		TradeOrder order = TradeOrder.createRefund(req, orignOrder);
		// 退款金额 = 订单金额 - 手续费
		Integer amt = order.getAmount() - order.getMerchFee();
		boolean isD0 = false;
		if (orignOrder.getSettleDate().equals(FSDate.getDate())) {
			isD0 = true;
		}
		AccountBalanceChangeResp accountRsp = accountService.subMoney(isD0, order.getChannelCode(),
				order.getMerchCode(), amt);
		if (!"SUCCESS".equals(accountRsp.getRespCode())) {
			// 余额不足是不需要撤销的
			rsp.setCodeAndMsg(Resp.Fail.getCode(), accountRsp.getRespMsg());
			order.setBalance(0L);
			order.setOrderStatus(OrderStatus.Fail.getValue());
			order.setRespCode(accountRsp.getRespCode());
			order.setRespMsg(accountRsp.getRespMsg());
			order.setIsD0(isD0);
			order.save();
			// 明确失败通知商户
			NotifyThread.getInstance().addNotifyOrder(order);
			return rsp;
		}
		// 虚账减钱成功
		order.setBalance(Long.valueOf(accountRsp.getBalance()));
		order.setIsD0(isD0);
		IChannel channel = ChannelFactory.get(orignOrder.getChannelCode());
		try {
			rsp = channel.refund(req, order, orignOrder);
		} catch (Exception e) {
			FSLog.api.error("refund exception ->" + req.getMerchCode() + " merchOrderNo=" + req.getMerchOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			setOrderStatusByResp(rsp, order);
			if (rsp.getRespCode().equals(Resp.Fail.getCode())) {
				order.setOrderStatus(OrderStatus.Fail.getValue());
				accountRsp = accountService.addMoney(isD0, order.getChannelCode(), order.getMerchCode(), amt);
				NotifyThread.getInstance().addNotifyOrder(order);
			}
			rsp.setOrderNo(order.getOrderNo());
			order.save();
		}
		return rsp;
	}

	public BaseResp charge(AccountBalanceChangeReq req, TradeStrategy ts) {
		AccountBalanceChangeResp rsp = new AccountBalanceChangeResp(req);
		rsp.setChannelNo(ts.getChannelCode());
		Integer merchFee = new CalcFeeService().getFee(Integer.valueOf(req.getAmount()), ts.getMerchFeeId());
		TradeOrder order = new TradeOrder();
		order.setId(FSIDGenerate.getUUID());
		order.setOrderNo(FSIDGenerate.nextOrderNo());
		order.setMerchOrderNo(req.getRequestOrderNo());
		order.setOrgCode(req.getOrgCode());
		order.setMerchCode(req.getMerchCode());
		order.setPayType(req.getPayType());
		order.setChannelCode(ts.getChannelCode());
		order.setAmount(Integer.valueOf(req.getAmount()));
		order.setMerchFee(merchFee);
		order.setSettleDate(FSDate.getDate());
		order.setCreateTime(FSDate.getDateTime());
		order.setPayTime(order.getCreateTime());
		order.setIsD0(false);
		order.setRemark(req.getRemark());

		// 实际充值金额需要扣除手续费
		Long chargeAmt = order.getAmount().longValue() - order.getMerchFee().longValue();
		AccountBalanceChangeResp chargeRsp = accountService.addMoney(false, order.getChannelCode(),
				order.getMerchCode(), chargeAmt.intValue());
		if (chargeRsp.getRespCode().equalsIgnoreCase("SUCCESS")) {
			order.setOrderStatus(OrderStatus.Success.getValue());
			order.setBalance(Long.valueOf(chargeRsp.getBalance()));
			rsp.setCodeAndMsg(Resp.Success.getCode(), chargeRsp.getRespMsg());
			rsp.setBalance(chargeRsp.getBalance());
		} else {
			order.setOrderStatus(OrderStatus.Fail.getValue());
			rsp.setCodeAndMsg(Resp.Fail.getCode(), chargeRsp.getRespMsg());
		}
		order.setRespCode(Resp.Fail.getCode());
		order.setRespMsg(chargeRsp.getRespMsg());
		order.save();
		return rsp;
	}

	public BaseResp transfer(AccountTransferReq req, TradeStrategy ts) {
		AccountTransferResp resp = new AccountTransferResp(req);
		TradeOrder orderOut = new TradeOrder();
		orderOut.setId(FSIDGenerate.getUUID());
		orderOut.setOrderNo(FSIDGenerate.nextOrderNo());
		orderOut.setMerchOrderNo(req.getRequestOrderNo());
		orderOut.setOrgCode(req.getOrgCode());
		orderOut.setMerchCode(req.getMerchCode());
		orderOut.setOtherMerchCode(req.getToAccountNo());
		orderOut.setPayType(req.getPayType());
		orderOut.setChannelCode(ts.getChannelCode());
		orderOut.setAmount(Integer.valueOf(req.getAmount()));
		orderOut.setMerchFee(0);
		orderOut.setSettleDate(FSDate.getDate());
		orderOut.setCreateTime(FSDate.getDateTime());
		orderOut.setPayTime(orderOut.getCreateTime());
		orderOut.setRemark(req.getRemark());
		orderOut.setIsD0(false);

		TradeOrder orderIn = new TradeOrder();
		orderIn.setId(FSIDGenerate.getUUID());
		orderIn.setOrderNo(FSIDGenerate.nextOrderNo());
		orderIn.setMerchOrderNo(req.getRequestOrderNo());
		orderIn.setMerchCode(req.getToAccountNo());
		orderIn.setOtherMerchCode(req.getFromAccountNo());
		orderIn.setPayType(PayType.TRANS_IN);
		orderIn.setChannelCode(ts.getChannelCode());
		orderIn.setAmount(Integer.valueOf(req.getAmount()));
		orderIn.setMerchFee(0);
		orderIn.setSettleDate(FSDate.getDate());
		orderIn.setCreateTime(FSDate.getDateTime());
		orderIn.setPayTime(orderIn.getCreateTime());
		orderIn.setRemark(req.getRemark());
		orderOut.setIsD0(false);

		FSLog.api.info("发送账户系统数据 ->" + FSJson.toString(req));
		AccountTransferResp transferResp = accountService.transfer(ts.getChannelCode(), req.getFromAccountNo(),
				req.getToAccountNo(), Long.valueOf(req.getAmount()));
		FSLog.api.info("账户系统响应数据 ->" + FSJson.toString(transferResp));

		if (transferResp.getRespCode().equalsIgnoreCase("SUCCESS")) {
			orderOut.setBalance(Long.valueOf(transferResp.getFromAccountBalance()));
			orderOut.setRespCode(Resp.Success.getCode());
			orderOut.setRespMsg(transferResp.getRespMsg());
			orderOut.setOrderStatus(OrderStatus.Success.getValue());
			orderIn.setBalance(Long.valueOf(transferResp.getToAccountBalance()));
			orderIn.setRespCode(Resp.Success.getCode());
			orderIn.setRespMsg(transferResp.getRespMsg());
			orderIn.setOrderStatus(OrderStatus.Success.getValue());
			resp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			resp.setFromAccountBalance(transferResp.getFromAccountBalance());
			resp.setToAccountBalance(transferResp.getToAccountBalance());
		} else {
			resp.setCodeAndMsg(Resp.Fail.getCode(), "AC:" + transferResp.getRespMsg());
			orderOut.setRespCode(Resp.Fail.getCode());
			orderOut.setRespMsg(transferResp.getRespMsg());
			orderOut.setOrderStatus(OrderStatus.Fail.getValue());
			orderIn.setRespCode(Resp.Fail.getCode());
			orderIn.setRespMsg(transferResp.getRespMsg());
			orderIn.setOrderStatus(OrderStatus.Fail.getValue());
		}
		orderOut.save();
		orderIn.save();
		return resp;
	}

	/**
	 * 转账二维码支付
	 *
	 * @param req
	 * @return
	 */
	public BaseResp transferQrcode(TransferQrcodeReq req, TradeElement tradeElement) {
		TradeOrder order = TradeOrder.dao.createTransferQrcodeOrder(req, tradeElement);
		TransferQrcodeResp resp = null;
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			resp = channel.transferQrcode(req, order);
		} catch (Exception e) {
			FSLog.api.error("获取转账二维码发生异常:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
			resp.setQrcodeUrl("");
		} finally {
			order.save();
		}
		return resp;
	}

	/**
	 * 支付宝生活号及微信公众号支付
	 *
	 * @param req
	 * @return
	 */
	public BaseResp appidPay(AppidPayReq req, TradeElement tradeElement) {
		TradeOrder order = TradeOrder.dao.createAppidPayOrder(req, tradeElement);
		AppidPayResp resp = null;
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {//汇卡特殊处理:  交易策略配置关联的子商户号可以理解为汇卡机构号， 那么就可以知道这个商户轮训汇卡的哪些汇卡商户号了
			resp = channel.appidPay(req, order, tradeElement.getTradeStrategy().getChannelSubMerchCode());
		} catch (Exception e) {
			FSLog.api.error("支付宝生活号及微信公众号支付:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		} finally {
			order.save();
		}
		return resp;
	}

	/**
	 * 跨境微信公众号支付
	 *
	 * @param req
	 * @return
	 */
	public BaseResp wxgjappidPay(AppidWxgjPayReq req, TradeElement tradeElement) {
		TradeOrder order = TradeOrder.dao.createAppidWxgjPayOrder(req, tradeElement);
		AppidWxgjPayResp resp = null;
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			resp = channel.wxgjappidPay(req, order);
		} catch (Exception e) {
			FSLog.api.error("支付宝生活号及微信公众号支付:" + e);
			resp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		} finally {
			order.save();
		}
		return resp;
	}

	/**
	 * 根据resp的code来设置order的状态
	 *
	 * @param rsp
	 * @param order
	 */
	private void setOrderStatusByResp(BaseResp rsp, TradeOrder order) {
		order.setRespCode(rsp.getRespCode());
		order.setRespMsg(rsp.getRespMsg());

		if (order.getRespCode().equals(Resp.Success.getCode())) {
			if (order.getPayType().equals(PayType.UNION_PAY) || order.getPayType().equals(PayType.UNION_PAY_SUB)
					|| order.getPayType().equals(PayType.QUICK_PAY_SET)) {
				order.setOrderStatus(OrderStatus.Create.getValue());
			} else if (order.getPayType().equals(PayType.DF_PERSONAL)
					|| order.getPayType().equals(PayType.DF_COMPANY)) {
				order.setOrderStatus(OrderStatus.InProcess.getValue());
			} else {
				order.setOrderStatus(OrderStatus.InProcess.getValue());
			}
		} else if (order.getRespCode().equals(Resp.Fail.getCode())) {
			order.setOrderStatus(OrderStatus.Fail.getValue());
		} else {
			order.setOrderStatus(OrderStatus.Unknow.getValue());
		}

	}

	public BaseResp bindBankCard(BindBankCardReq req, TradeElement tradeElement) {
		BindBankCardResp rsp = new BindBankCardResp(req);
		TradeOrder order = new TradeOrder();
		order.setId(FSIDGenerate.getUUID());
		order.setOrderNo(FSIDGenerate.nextOrderNo());
		order.setOrgCode(req.getOrgCode());
		order.setMerchOrderNo(req.getMerchOrderNo());
		order.setMerchCode(req.getMerchCode());
		order.setPayType(req.getPayType());
		order.setAmount(0);
		order.setChannelCode(tradeElement.getTradeStrategy().getChannelCode());
		order.setMerchFee(0);
		order.setBalance(0L);
		order.setSettleDate(FSDate.getDate());
		order.setCreateTime(FSDate.getDateTime());
		order.setNotifyStatus(NotifyStatus.Wait.getValue());
		order.setCardType(req.getCardType());
		order.setIsInVirtualAccount(false);
		order.setGoodsName("快捷支付绑卡");

		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			rsp = channel.bindBankCard(req, order);
		} catch (Exception e) {
			FSLog.api.error("unionpay exception ->" + req.getMerchCode() + " merchOrderNo=" + req.getMerchOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			setOrderStatusByResp(rsp, order);
			rsp.setOrderNo(order.getOrderNo());
			order.setIsD0(false);
			order.save();
		}
		return rsp;
	}

	public BaseResp bindBankCardVerify(BindBankCardVerifyReq req, TradeElement tradeElement) {
		BindBankCardVerifyResp rsp = new BindBankCardVerifyResp(req);
		TradeOrder order = TradeOrder.dao.selectByOrderNo(req.getOrderNo());
		IChannel channel = ChannelFactory.get(tradeElement.getTradeStrategy().getChannelCode());
		try {
			rsp = channel.bindBankCardVerify(req, order);
		} catch (Exception e) {
			FSLog.api.error("unionpay exception ->" + req.getMerchCode() + " merchOrderNo=" + req.getMerchOrderNo(), e);
			rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_EXCEPTION);
		} finally {
			setOrderStatusByResp(rsp, order);
			order.setIsD0(false);
			order.update();
		}
		return rsp;
	}

}
